#ifndef __BASE_TYPES_COMMON_H__
#define __BASE_TYPES_COMMON_H__
#include <configProject.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stddef.h>

#define LOG_USE_FUNC_FLAG 1

#if DEVICE_PLATFORM_CONFIGURE == DEVICE_PLATFORM_LINUX
// for linux
#include <pthread.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#endif

enum logLevelEnum
{
    logLevelFatal = 0,
    logLevelError,
    logLevelWarn,
    logLevelInform,
    logLevelDebug,
    logLevelTrace,
};
extern int param_LogLevel;
#if LOG_USE_FUNC_FLAG == 0
#define printf_common(lev, fmt, lprt, ...)                                                                             \
    do                                                                                                                 \
    {                                                                                                                  \
        if (lev <= param_LogLevel)                                                                                     \
        {                                                                                                              \
            struct timeval tnow;                                                                                       \
            struct tm *tmnow;                                                                                          \
            gettimeofday(&tnow, NULL);                                                                                 \
            tmnow = localtime(&tnow.tv_sec);                                                                           \
            printf("[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%s,%d]" fmt "\n", tmnow->tm_year + 1900, tmnow->tm_mon + 1, \
                   tmnow->tm_mday, tmnow->tm_hour, tmnow->tm_min, tmnow->tm_sec, (int)tnow.tv_usec / 1000 % 1000,      \
                   lprt, __FILE__, __LINE__, ##__VA_ARGS__);                                                           \
        }                                                                                                              \
    } while (0);
#define printffatal(fmt, ...) printf_common(logLevelFatal, fmt, "fat", ##__VA_ARGS__)
#define printerror(fmt, ...) printf_common(logLevelError, fmt, "err", ##__VA_ARGS__)
#define printwarn(fmt, ...) printf_common(logLevelWarn, fmt, "war", ##__VA_ARGS__)
#define printinform(fmt, ...) printf_common(logLevelInform, fmt, "inf", ##__VA_ARGS__)
#define printdebug(fmt, ...) printf_common(logLevelDebug, fmt, "dbg", ##__VA_ARGS__)
#define printtrace(fmt, ...) printf_common(logLevelTrace, fmt, "tra", ##__VA_ARGS__)

// #define logfatal(fmt, ...) printffatal(fmt, ##__VA_ARGS__)
// #define logerror(fmt, ...) printerror(fmt, ##__VA_ARGS__)
// #define logwarn(fmt, ...) printwarn(fmt, ##__VA_ARGS__)
// #define loginform(fmt, ...) printinform(fmt, ##__VA_ARGS__)
// #define logdebug(fmt, ...) printdebug(fmt, ##__VA_ARGS__)
// #define logtrace(fmt, ...) printtrace(fmt, ##__VA_ARGS__)
#else
int __attribute__((format(printf, 4, 5))) clogCommon(int lev, const char *lfile, int lline, const char *fmt, ...);
#define logfatal(fmt, ...) clogCommon(logLevelFatal, __FILE__, __LINE__, " " fmt, ##__VA_ARGS__)
#define logerror(fmt, ...) clogCommon(logLevelError, __FILE__, __LINE__, " " fmt, ##__VA_ARGS__)
#define logwarn(fmt, ...) clogCommon(logLevelWarn, __FILE__, __LINE__, " " fmt, ##__VA_ARGS__)
#define loginform(fmt, ...) clogCommon(logLevelInform, __FILE__, __LINE__, " " fmt, ##__VA_ARGS__)
#define logdebug(fmt, ...) clogCommon(logLevelDebug, __FILE__, __LINE__, " " fmt, ##__VA_ARGS__)
#define logtrace(fmt, ...) clogCommon(logLevelTrace, __FILE__, __LINE__, " " fmt, ##__VA_ARGS__)
#endif

// 通过成员地址找到结构体变量地址。
#define container_of(ptr, type, member) ((type *)((char *)(ptr) - (char *)(&((type *)0)->member)))
// 求数组长度
#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
// 将整数、浮点数控制在一个范围。
#define LIMIT_VAL(a, min, max) ((a) > (max) ? (max) : ((a) < (min) ? (min) : (a)))
// 循环加
#define CYCLE_ADD(a, add, len) (((a) + (add)) % (len))
// 交换整形数据宏
#define SWAP_BASE_VAL(a, b) (a ^= b, b ^= a, a ^= b)

size_t memcpypro(void *dest, size_t destsize, const void *src, size_t srcsize);
size_t memcpyStr(void *dest, size_t destsize, const char *src);

#if DEVICE_PLATFORM_CONFIGURE == DEVICE_PLATFORM_LINUX
typedef uint64_t sysTmrType;
#else
typedef uint32_t sysTmrType;
#endif
sysTmrType systemNowMs();
#define sysTmrMsDefine(ctimeName) sysTmrType ctimeName
#define sysTmrMsBegin(ct) (ct = systemNowMs())
#define sysTmrMsDefBegin(ctimeName) sysTmrType ctimeName = systemNowMs();
#define sysTmrMsRunMs(ct) (systemNowMs() - ct)
#define sysTmrMsRunSec(ct) (sysTmrMsRunMs(ct) / 1000)

#endif
